package account

import (
	"context"
	"crypto/ecdsa"
	"fmt"
	"github.com/ethereum/go-ethereum/accounts/keystore"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/common/hexutil"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"golang.org/x/crypto/sha3"
	"io/ioutil"
	"log"
	"math"
	"math/big"
	"os"
	"regexp"
)

func Account() {
	address := common.HexToAddress("0x71c7656ec7ab88b098defb751b7401b5f6d8976f")
	fmt.Printf("%v\n", address.Hex())
	fmt.Printf("%v\n", address.Hash().Hex())
	fmt.Printf("%v\n", address.Bytes())
}
var client * ethclient.Client

func init() {
	var err error
	client, err = ethclient.Dial("HTTP://127.0.0.1:8545")
	if err != nil {
		log.Fatalf("init: %v\n", err.Error())
	}
}
func Balance()  {
	client, err := ethclient.Dial("HTTP://127.0.0.1:8545")
	if err != nil {
		log.Fatalf(err.Error())
	}
	fmt.Printf("%v\n", "connection sucucess")
	account := common.HexToAddress("0x2e66Cd1543d55B30666aA6e8220e750645EE8dcA")
	balance, err := client.BalanceAt(context.Background(), account, nil)
	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Printf("%v\n", balance)
	b := new(big.Float)
	b.SetString(balance.String())
	ethVal := new(big.Float).Quo(b, big.NewFloat(math.Pow10(18)))
	fmt.Printf("ethVal:%v\n", ethVal)
	pendingBalance, err := client.PendingBalanceAt(context.Background(), account)
	if err != nil {
		log.Fatal(err.Error())
	}
	fmt.Printf("pendingBalance: %v\n", pendingBalance)
}
func CreatWallet()  {
	privateKey, err := crypto.GenerateKey()
	if err != nil {
		fmt.Printf("err1: %v\n", "err1")
		log.Fatal(err.Error())
	}
	privateKeyBytes := crypto.FromECDSA(privateKey)
	fmt.Printf("%v\n", hexutil.Encode(privateKeyBytes[2:]))
	publicKey := privateKey.Public()
	publicKeyECDSA,ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		log.Fatal("cannot assert type: publickey is not of a type *ecdsa.PublicKey")
		fmt.Printf("err2: %v\n", "err2")
	}
	// //publicKeyBytes := crypto.FromECDSA(publicKeyECDSA)
	publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
	fmt.Printf("%v\n", hexutil.Encode(publicKeyBytes[4:]))
	address := crypto.PubkeyToAddress(*publicKeyECDSA).Hex()
	fmt.Printf("%v\n", address)
	hash := sha3.NewLegacyKeccak256()
	hash.Write(publicKeyBytes[1:])
	fmt.Printf("%v\n", hexutil.Encode(hash.Sum(nil)[12:]))
}
func CreateKeystore()  {
	ks := keystore.NewKeyStore("./wallets", keystore.StandardScryptN, keystore.StandardScryptP)
	password := "secret"
	account, err := ks.NewAccount(password)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("account Hex:%v\n", account.Address.Hex())

	file := "./wallets/UTC--2021-09-06T16-37-20.583309100Z--15f64571d1e3e2e04bdb87a7c4f3666f2f1167a6"
	keystore.NewKeyStore("./tmp", keystore.StandardScryptN, keystore.StandardScryptP)
	jsonBytes, err := ioutil.ReadFile(file)
	if err != nil {
		log.Fatal(err)
	}
	account1, err := ks.Import(jsonBytes, password, password)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%v\n", account1.Address.Hex())
	if err = os.Remove(file); err != nil {
		log.Fatal(err)
	}
}
func CheckAddress()  {
	re := regexp.MustCompile("^0x[0-9a-fA-F]{40}$")
	fmt.Printf("check1: %v\n", re.MatchString("0x323b5d4c32345ced77393b3530b1eed0f346429d"))
	fmt.Printf("check2: %v\n", re.MatchString("0xZYXb5d4c32345ced77393b3530b1eed0f346429d"))
}
func CheckContractAddress()  {
	address := common.HexToAddress("")
	bytecode, err := client.CodeAt(context.Background(), address, nil)
	if err != nil {
		log.Fatal(err)
	}
	isContract := len(bytecode) > 0
	fmt.Printf("%v\n", isContract)
}